package cn.mulanbay.log.web.controller;

import cn.mulanbay.api.system.bean.RemoteSystemLog;
import cn.mulanbay.api.system.service.RemoteMessageService;
import cn.mulanbay.business.bean.SysMessageBean;
import cn.mulanbay.business.handler.ThreadPoolHandler;
import cn.mulanbay.common.bean.ResultBean;
import cn.mulanbay.common.util.BeanCopy;
import cn.mulanbay.common.util.DateUtil;
import cn.mulanbay.common.util.StringUtil;
import cn.mulanbay.log.handler.LogHandler;
import cn.mulanbay.log.persistent.service.OperationLogService;
import cn.mulanbay.log.persistent.service.SystemLogService;
import cn.mulanbay.log.web.bean.request.systemLog.SystemLogSearch;
import cn.mulanbay.log.web.bean.response.systemLog.OperationBeanDetailVo;
import cn.mulanbay.persistent.entity.ErrorCodeDefine;
import cn.mulanbay.persistent.entity.SystemLog;
import cn.mulanbay.persistent.entity.User;
import cn.mulanbay.persistent.enums.IdFieldType;
import cn.mulanbay.persistent.enums.LogLevel;
import cn.mulanbay.persistent.enums.MessageSource;
import cn.mulanbay.persistent.enums.MessageType;
import cn.mulanbay.web.controller.BaseController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 系统日志
 *
 * @author fenghong
 * @create 2022-01-16 10:00
 */
@RestController
@RequestMapping("/systemLog")
public class SystemLogController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(SystemLogController.class);

    @Autowired
    SystemLogService systemLogService;

    @Autowired
    OperationLogService operationLogService;

    @Autowired
    ThreadPoolHandler threadPoolHandler;

    @Autowired
    LogHandler logHandler;

    @Lazy
    @Autowired
    RemoteMessageService remoteMessageService;

    /**
     * 获取列表数据
     *
     * @return
     */
    @RequestMapping(value = "/getData", method = RequestMethod.GET)
    public ResultBean getData(SystemLogSearch sf) {
        return callbackDataGrid(systemLogService.getDataList(sf));
    }


    /**
     * 获取日志参数
     *
     * @return
     */
    @RequestMapping(value = "/getParas", method = RequestMethod.GET)
    public ResultBean getParas(Long id) {
        SystemLog br = systemLogService.getById(id);
        return callback(br.getParas());
    }

    /**
     * 创建
     *
     * @return
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public ResultBean create(@RequestBody @Valid RemoteSystemLog sl) {
        logger.info("增加系统日志，title:{},content:{}",sl.getTitle(),sl.getContent());
        LogLevel level = LogLevel.WARNING;
        ErrorCodeDefine ecd = systemLogService.getErrorCodeDefine(sl.getErrorCode());
        if(ecd!=null){
            if(!ecd.getLoggable()){
                return callback(null);
            }
            level = ecd.getLevel();
        }
        SystemLog log = new SystemLog();
        BeanCopy.copyProperties(sl,log);
        log.setLogLevel(level);
        log.setStoreTime(LocalDateTime.now());
        log.setStoreDuration(DateUtil.getDurationMills(log.getOccurTime(),log.getStoreTime()));
        log.setCreatedTime(LocalDateTime.now());

        Long userId = log.getUserId();
        if(userId==null){
            log.setUserId(0L);
            log.setUsername("系统用户");
        }else if(userId>0&&StringUtil.isEmpty(log.getUsername())){
            User user = logHandler.getUser(log.getUserId());
            if(user!=null){
                log.setUsername(user.getUsername());
            }
        }
        systemLogService.save(log);
        this.addSysMessage(log);
        logHandler.updateErrorCodeCount(sl.getErrorCode(),1);
        return callback(null);
    }

    /**
     * 添加系统消息
     * @param log
     */
    private void addSysMessage(SystemLog log){
        try {
            threadPoolHandler.pushThread(() -> {
                SysMessageBean smb = new SysMessageBean();
                smb.setMessageType(MessageType.WX);
                smb.setSource(MessageSource.OP);
                smb.setSourceId(log.getId());
                smb.setTitle(log.getTitle());
                smb.setContent(log.getContent());
                smb.setCode(log.getErrorCode());
                remoteMessageService.addSysMsg(smb);
            });
        } catch (Exception e) {
            logger.error("添加系统消息异常",e);
        }
    }

    /**
     * 获取详情
     *
     * @return
     */
    @RequestMapping(value = "/get", method = RequestMethod.GET)
    public ResultBean get(Long id) {
        SystemLog br = systemLogService.getById(id);
        return callback(br);
    }

    /**
     * 查询被操作的业务对象的数据
     *
     * @param id 为操作日志的记录号
     * @return
     */
    @RequestMapping(value = "/getBeanDetail", method = RequestMethod.GET)
    public ResultBean getBeanDetail(Long id) {
        SystemLog br = systemLogService.getById(id);
        String idValue = br.getIdValue();
        if (StringUtil.isEmpty(idValue)) {
            return callbackErrorInfo("没有操针对象主键信息");
        } else {
            OperationBeanDetailVo response = new OperationBeanDetailVo();
            response.setIdValue(idValue);
//            response.setBeanName(br.getSystemFunction().getBeanName());
//            Serializable bussId = formatIdValue(br.getSystemFunction().getIdFieldType(), idValue);
//            Object o = baseService.getObject(br.getSystemFunction().getBeanName(), bussId, br.getSystemFunction().getIdField());
//            response.setBeanData(o);
            return callback(response);
        }
    }

    private Serializable formatIdValue(IdFieldType idFieldType, String idValue) {
        Serializable bussId = null;
        if (idFieldType == IdFieldType.LONG) {
            bussId = Long.valueOf(idValue);
        } else if (idFieldType == IdFieldType.INTEGER) {
            bussId = Integer.valueOf(idValue);
        } else if (idFieldType == IdFieldType.SHORT) {
            bussId = Short.valueOf(idValue);
        } else {
            bussId = idValue;
        }
        return bussId;
    }
}